package com.sduept.nwld.dataserver.manager.etl;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.entity.FaultRecordWrapper;
import com.sduept.bigdata.fault.enums.RegexTypeEnum;
import com.sduept.bigdata.fault.parser.entity.StandardLibrary;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.cim.ledger.model.SubstationLedger;
import com.sduept.cim.model.extend.LineSegment;
import com.sduept.generator.ObjectId;
import com.sduept.nwld.dataserver.model.daily.Runlog;
import com.sduept.nwld.dataserver.util.CimUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 直流线路故障抽取
 * 
 * @author Author
 *
 */
@Service
public class AcLineFaultDataETLManager extends FaultETLDataManager {

	@Autowired
	private SubstationLedgerManager stationLedgerM;
	/**
	 * 故障记录抽取
	 */
	public void extracFaultRecord(Runlog record, Map<String, List<StandardLibrary>> map) throws Exception {
		if (StringUtils.isEmpty(record.getLog_contents())) {
			return;
		}
		List<StandardLibrary> list = map.get(RegexTypeEnum.ACLINE_FAULT_REGEX.getCode());
		boolean matcher = FaultRegexUtil.isMatcher(record.getLog_contents(), list);
		if (!matcher) {
			return;
		}
		List<StandardLibrary> dataList = map.get(RegexTypeEnum.ACLINE_DATA_REGEX.getCode());
		List<StandardLibrary> timeList = map.get(RegexTypeEnum.SIGN_FAULT_TIME_REGEX.getCode());
		List<StandardLibrary> singleFilters = map.get(RegexTypeEnum.SINGLE_ACLINE_FAULT_FILTER.getCode());
		String[] strings = record.getLog_contents().split(DEFAULT_SPLIT_REGEX);
		for (String faultDesc : strings) {
			boolean singlefilter = FaultRegexUtil.isMatcher(faultDesc, singleFilters);
			if(singlefilter){
				continue;
			}
			boolean singleMatcher = FaultRegexUtil.isMatcher(faultDesc, list);
			if (!singleMatcher) {
				continue;
			}
			FaultRecord fault = new FaultRecord();
			fault.setSource(4);
			Date faultTime = getFaultTime(faultDesc, record.getTime(), timeList);
			if (null == faultTime) {
				continue;
			}
			fault.setId(ObjectId.get().toString());
			fault.setFaultTime(faultTime);
			String v = find1("([0-9]+)kV", faultDesc);
			fault.setVoltage(v.equals("") ? null : Integer.parseInt(v));
			fault.setFaultPhase(find1("([A-Za-z]+)相", faultDesc));
			fault.setFaultType(getFaultType(faultDesc, fault.getFaultPhase()));
			fault.setEtype("线路");
			String equipment = getFirstMatcher(faultDesc, dataList);
			equipment = CimUtils.convertKVAndRegion(equipment);
			if (StringUtils.isEmpty(equipment)) {
				continue;
			}
			String type = getLineType(equipment);
			if (SIGN_DC_LINE.equals(type)) {
				continue;
			}
			fault.setEquipment(equipment);
			LineSegment acline = queryLineCimId(equipment);
			if (acline != null) {
				fault.setEquipment(acline.getName());
				fault.setEquipment_id(acline.getId());
				fault.setStationId(acline.getStartST());
				fault.setStationId2(acline.getEndST());
				fault.setStationName(acline.getStartStName());
				fault.setStationName2(acline.getEndStName());
				if (null == fault.getVoltage()) {
					fault.setVoltage((int) acline.getStandVoltagelevel());
				}
			}
			if (fault.getVoltage() == null || fault.getVoltage() < 500|| StringUtils.isEmpty(fault.getEquipment_id())) {
				continue;
			}
			if (StringUtils.isEmpty(fault.getRank()) && StringUtils.isNotEmpty(fault.getStationId())) {
				SubstationLedger stationLedger = stationLedgerM.findSubstationLedger(fault.getStationId());
				if(null != stationLedger) {
					fault.setRank(stationLedger.getPrimaryEquipmentScope());
				}
			}
			fm.saveFaultRecord(new FaultRecordWrapper(fault));
		}
	}

	/**
	 * 故障的巡线结果抽取，包括 ：故障原因、故障杆塔以及巡线结果
	 */
	public void extracFaultResult(Runlog record, Map<String, List<StandardLibrary>> map) throws Exception {
		List<StandardLibrary> list = map.get(RegexTypeEnum.RESULT_DATA_REGEX.getCode());
		if (!FaultRegexUtil.isMatcher(record.getLog_contents(), list)) {
			return;
		}
		String[] strings = record.getLog_contents().split("。");
		for (String s : strings) {
			if (s.contains(SIGN_RESULT_FAULT)) {
				updateByInspectionResults(s, record.getTime(), map);
			}
		}
	}

	/**
	 * 故障过程抽取，包括：保护测距、录波测距以及行波测距，并更新到故障报告中去
	 */
	public void extracFaultProcess(Runlog record, Map<String, List<StandardLibrary>> map) throws Exception {
		if (StringUtils.isEmpty(record.getLog_contents())) {
			return;
		}
		String signAction = map.get(RegexTypeEnum.ACTION_PROTECT_CONDITION_REGEX.getCode()).get(0).getName();
		if (StringUtils.isEmpty(signAction)) {
			signAction = SIGN_PROTECT_ACTION_CONDITION;
		}
		if (!record.getLog_contents().contains(signAction)) {
			return;
		}
		// 更新两相接地两相相间故障原因与故障描述
		String sign = record.getLog_contents().substring(0, record.getLog_contents().indexOf(signAction));
		sign = sign.replaceAll(SIGN_VOLTAGE_REGEX, "");
		if (!sign.contains("报")) {
			return;
		}
		String[] split = sign.split("报");
		if (split.length != 2) {
			return;
		}
		String subName = split[0];
		if (StringUtils.isEmpty(subName)) {
			return;
		}
		String devName = split[1];
		if (StringUtils.isEmpty(devName)) {
			return;
		}
		String lineType = getLineType(devName);
		if (!lineType.equals(SIGN_AC_LINE)) {
			return;
		}
		LineSegment lineSegment = getLineSegmentByName(devName, map);
		List<FaultRecord> condition = null;
		if (null == lineSegment) {
			condition = getRecords(null, devName, record);
		} else {
			condition = getRecords(lineSegment.getId(), null, record);
		}
		if (condition.size() == 0) {
			return;
		}
		for (FaultRecord faRecord : condition) {
			if (StringUtils.isEmpty(faRecord.getRanging()) || !isContainStation(faRecord.getRanging(), subName)) {
				// 更新故障类型
				if (StringUtils.isEmpty(faRecord.getFaultType()) && StringUtils.isNotEmpty(faRecord.getFaultPhase())) {
					String faultType = getFaultType(record.getLog_contents(), faRecord.getFaultPhase());
					faRecord.setFaultType(faultType);
				}
				// 更新测距信息
				String[] rtn = getRanging(subName, record.getLog_contents(), map);
				if (null == rtn) {
					continue;
				}
				if (StringUtils.isEmpty(faRecord.getRanging()) && StringUtils.isNotEmpty(rtn[1])) {
					faRecord.setRanging(rtn[1]);
				} else if (StringUtils.isNotEmpty(rtn[1])) {
					faRecord.setRanging(faRecord.getRanging() + rtn[1]);
				}
				if (StringUtils.isEmpty(rtn[0])) {
					continue;
				}
				try {
					// 更新故障报告中测距
					updateFaultReportByFaultRecord(faRecord, rtn[0]);
					// 更新杆塔
					updateST(faRecord, map);
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 如果杆塔为空，使用测距计算出的杆塔号
				if (faRecord.getStartPole() == null) {
					try {
						fm.setupFaultTower(faRecord);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			dao.createOrUpdate(faRecord, FaultRecord.class);
		}

	}

	/**
	 * 根据名称获取线路
	 * 
	 * @param name
	 * @param map
	 * @return
	 */
	private LineSegment getLineSegmentByName(String name, Map<String, List<StandardLibrary>> map) {
		LineSegment rtn = null;
		List<StandardLibrary> list = map.get(RegexTypeEnum.ACLINE_DATA_REGEX.getCode());
		String lineName = getFirstMatcher(name, list);
		if (StringUtils.isNotEmpty(lineName)) {
			rtn = queryLineCimId(lineName);
		}
		return rtn;
	}

	/**
	 * 根据描述生成 交流线路故障的测距信息 返回值中 s[0] 代表用来更新故障报告的数据，s[1]代表用来存储的数据
	 * 
	 * @param subName
	 * @param desc
	 * @return
	 */
	public String[] getRanging(String subName, String desc, Map<String, List<StandardLibrary>> map) {
		String[] rtns = new String[2];
		String s = subName + "：";
		String temp = null;
		String rtn = desc.substring(desc.indexOf(SIGN_PROTECT_ACTION_CONDITION), desc.length());
		String[] strings = null;
		String spiltSign="";
		List<StandardLibrary> splitList = map.get(RegexTypeEnum.SIGN_PROTECT_RANGING_REGEX.getCode());
		if(null==splitList||splitList.size()==0){
			spiltSign=SIGN_PROTECT_RANGING_REGEX;
		}else{
			spiltSign=splitList.get(0).getName();
		}
		if (rtn.contains(spiltSign)) {
			strings = rtn.split(spiltSign);
		} else {
			strings = rtn.split("km");
		}
		if (null == strings) {
			return rtns;
		}
		List<StandardLibrary> oneList = map.get(RegexTypeEnum.LINE_PROTECT_ONE_REGEX.getCode());
		List<StandardLibrary> twoList = map.get(RegexTypeEnum.LINE_PROTECT_TWO_REGEX.getCode());
		List<StandardLibrary> threeList = map.get(RegexTypeEnum.LINE_PROTECT_THREE_REGEX.getCode());
		// 主保护测距
		for (String str : strings) {
			str = str.replaceAll("\n", "").replace("\r", "");
			if (FaultRegexUtil.isMatcher(str, oneList)) {
				String dis = DealWithWaveRanG(str);
				if (StringUtils.isNotEmpty(dis)) {
					s = s + SIGN_PROTECT_ONE + dis + "km，";
				}
			} else if (FaultRegexUtil.isMatcher(str, twoList)) {
				String dis = DealWithWaveRanG(str);
				if (StringUtils.isNotEmpty(dis)) {
					s = s + SIGN_PROTECT_TWO + dis + "km，";
				}
			} else if (FaultRegexUtil.isMatcher(str, threeList)) {
				String dis = DealWithWaveRanG(str);
				if (StringUtils.isNotEmpty(dis)) {
					s = s + SIGN_PROTECT_THREE + dis + "km，";
				}
			}
		}
		// 录波测距
		if (desc.contains(SIGN_WAVE_RANG)) {
			List<StandardLibrary> list = map.get(RegexTypeEnum.WAVE_RANING_DATA_REGEX.getCode());
			String range = getFirstMatcher(desc, list);
			if (StringUtils.isNotEmpty(range)) {
				s = s + range + "，";
			}
		}
		// 行波测距
		if (desc.contains(SIGN_TRAVEL_RANG)) {
			List<StandardLibrary> list = map.get(RegexTypeEnum.TRAVEL_RANG_DATA_REGEX.getCode());
			String range = getFirstMatcher(desc, list);
			if (StringUtils.isNotEmpty(range)) {
				s = s + range + "；";
				String tmp = range.replaceAll(SIGN_NUMBER_REGEX, "");
				if (StringUtils.isNotEmpty(tmp)) {
					temp = subName + "：" + tmp + "km；";
				}
			}
		}
		if (!s.endsWith("；")) {
			if (s.endsWith("，")) {
				s = s.substring(0, s.lastIndexOf("，"));
			}
			s = s + "；";
		}
		rtns[0] = s;
		rtns[1] = temp;
		return rtns;
	}

}
